﻿using System;
using System.Net;
using System.Net.Sockets;
using CS.Diagnostics;

namespace CS.Beehive
{

    /// <summary>
    /// Tcp连接中用到的基础数据和方法
    /// </summary>
    public abstract class TcpSetting
    {

        /// <summary>
        /// 全局同步锁
        /// </summary>
        protected readonly object SyncLock = new object();
        /// <summary>
        /// + 类同步锁
        /// </summary>
        protected  readonly object AddSyncLock = new object();
        /// <summary>
        /// - 类同步锁
        /// </summary>
        protected  readonly object RemoveSyncLock = new object();

        /// <summary>
        /// 接受到的字节数
        /// </summary>
        public long ReceivedByteSize;
        /// <summary>
        /// 发送出去的字节数
        /// </summary>
        public long SentByteSize;
        /// <summary>
        /// 接收IO
        /// </summary>
        public long ReceiveIO;
        /// <summary>
        /// 发送IO
        /// </summary>
        public long SendIO;


        /// <summary>
        /// 指示数据在此计算机结构中存储时的字节顺序
        /// <remarks>
        /// 如果结构为 Little-endian，则该值为 true；如果结构为 Big-endian，则该值为 false。
        /// 不同的计算机结构采用不同的字节顺序存储数据。
        /// " Big-endian”表示最大的有效字节位于单词的左端。
        /// " Little-endian”表示最大的有效字节位于单词的右端。
        /// </remarks>
        /// </summary>
        public bool IsLittleEndian { get; set; }

        private int _receiveBufferSize;
        /// <summary>
        /// 缓存区大小,4K(Linux:4096),8k(Windows:8192)
        /// </summary>
        public int BufferSize
        {
            get { return _receiveBufferSize; }
            set { _receiveBufferSize = value.ToInt(8192, 4096, 1048576); }
        }

        /// <summary>
        /// 重置数据统计
        /// </summary>
        public void ReSet()
        {
            lock (SyncLock)
            {
                ReceivedByteSize = 0;
                SentByteSize = 0;
                ReceiveIO = 0;
                SendIO = 0;
            }
        }

        /// <summary>
        /// 释放连接的Socket
        /// </summary>
        /// <param name="clientSocket"></param>
        public static void ReleaseSocket(Socket clientSocket)
        {
            if (clientSocket == null) return;
            lock (clientSocket)
            {
                try
                {
                    clientSocket.Shutdown(SocketShutdown.Both);
                }
                catch (Exception ex)
                {
                    Tracer.Error(ex);
                    //throw;
                }
                try
                {
                    clientSocket.Close();
                }
                catch (Exception ex)
                {
                    Tracer.Error(ex);
                    //throw;
                }
            }
        }

    }



    /// <summary>
    /// 服务端的相关初始化数据
    /// </summary>
    public abstract class TcpServerSetting : TcpSetting
    {
        /// <summary>
        /// 默认构造
        /// </summary>
        protected TcpServerSetting()
        {
            ServerIp = IPAddress.Any;
            ConnectPoolSize = 32;
            MaxConnections = 1000;
            SameIpMaxConnections = 500; //TODO:调试中的数据
            BufferSize = 4;//4096;//4K(Linux:4096);8K(Windows:8192);
            ReadWritePoolSize = MaxConnections * 2; //默认为连接数的2倍
        }

        /// <summary>
        /// TcpServer的IPV4地址，如果是 IPAddress.Any 则表示侦听所有网络接口上的通信，默认为 IPAddress.Any
        /// </summary>
        public IPAddress ServerIp { get; set; }

        /// <summary>
        /// 最大连接数，默认10
        /// </summary>
        public int MaxConnections { get; set; }

        /// <summary>
        /// 同一IP最多连接数，默认2
        /// </summary>
        public int SameIpMaxConnections { get; set; }



        private int _connectPoolSize = 32;
        /// <summary>
        /// 连接池初大小，默认32
        /// </summary>
        public int ConnectPoolSize
        {
            get { return _connectPoolSize; }
            set { _connectPoolSize = value.ToInt(128, 2, 1024); }
        }

        /// <summary>
        /// 读写池大小，默认为连接数的2倍，禁止外部修改
        /// </summary>
        internal protected int ReadWritePoolSize { get; set; }

    }

    /// <summary>
    /// 默认的初始化
    /// </summary>
    public class DefaultTcpServerSetting : TcpServerSetting
    {
    }

    ///// <summary>
    ///// 客户端的默认初始化
    ///// </summary>
    //public class DefaultTcpClientSetting : TcpSetting
    //{
    //}

}